package algebra.op;

import java.util.HashSet;
import java.util.Set;

import option.QueryKeywords;

import utils.Display;

import kb.DescriptionLogicsKB;
//import algebra.plan.CachedIndex;
import algebra.query.indexing.SecondaryIndex;

import entities.role.Role;

public class ScanOP extends AlgebraicOP {
	private final AlgebraicOP sub;
	private final SecondaryIndex idx;

	// private DescriptionLogicsKB kb;

	public ScanOP(AlgebraicOP sub, SecondaryIndex si) {
		super();
		this.sub = sub;
		this.idx = si;
	}

	public AlgebraicOP getSubquery() {
		return this.sub;
	}

	public SecondaryIndex getSecondaryIndex() {
		return this.idx;
	}

	// public void setSecondaryIndex(SecondaryIndex si){
	// this.idx = si;
	// }

	// public void removeCacheIndex(){
	// this.idx = null;
	// }

	@Override
	public boolean isPure() {
		return true;
	}

	@Override
	public String toString() {
		return Display.QSCANUNICODE + "_" + this.idx.shortName() + "_" + "("
				+ this.sub.toString() + ")";
	}

	@Override
	public String toSerializedString() {
		return " (" + QueryKeywords.QSCAN + ":" + this.idx.shortName() + " "
				+ this.sub.toSerializedString() + ") ";
	}

	@Override
	public DescriptionLogicsKB getPlanEvalKB() {
		return null;
	}

	@Override
	// this method is optional, as we will never ask about a plan's features
	public Set<Role> extractFeatures() {
		Set<Role> fs = new HashSet<Role>();
		fs.addAll(this.sub.extractFeatures());
		return fs;
	}

	@Override
	public Set<String> extractConstants() {
		Set<String> ks = new HashSet<String>();
		ks.addAll(this.sub.extractConstants());
		if (this.idx != null) {
			ks.addAll(this.idx.getCi().extractConstants());
		}
		return ks;
	}

	@Override
	public boolean isLeaf() {
		return false;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((idx == null) ? 0 : idx.hashCode());
		result = prime * result + ((sub == null) ? 0 : sub.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (!(obj instanceof ScanOP))
			return false;
		ScanOP other = (ScanOP) obj;
		if (idx == null) {
			if (other.idx != null)
				return false;
		} else if (!idx.equals(other.idx))
			return false;
		if (sub == null) {
			if (other.sub != null)
				return false;
		} else if (!sub.equals(other.sub))
			return false;
		return true;
	}

	@Override
	public AlgebraicOP getKFreeVersion() {
		return this;
	}

}
